package com.hnust.service.impl;

import com.hnust.api.SubjectApis;
import com.hnust.controller.subject.NewSubjectListController;
import com.hnust.domain.*;
import com.hnust.fx.DialogBuilder;
import com.hnust.service.SubjectServices;
import com.hnust.store.DataStore;
import com.hnust.store.SubjectStore;
import com.hnust.util.FileUpload;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXCheckBox;
import io.datafx.core.concurrent.ProcessChain;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.DirectoryChooser;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.List;


@Service("subjectServices")
public class SubjectServicesImpl implements SubjectServices {

    private static final Logger logger = LogManager.getLogger(SubjectServices.class);
    @Autowired
    private SubjectApis subjectApis;
    @Autowired
    private DataStore dataStore;
    @Autowired
    private SubjectStore subjectStore;
    @Autowired
    private NewSubjectListController newSubjectListController;
    @Override
    public void getCourseData(Label courseDataLabel, ComboBox<CourseData> comb, int selectedCourseIndex,
                              @Nullable String course_id) {
        ProcessChain.create().addRunnableInPlatformThread(() -> {
            comb.setItems(null);
            courseDataLabel.setText("获取课程列表中...");
        }).addSupplierInExecutor(() -> subjectApis.getCourseData(dataStore.getTeacher_id()))
                .addConsumerInPlatformThread((result) -> {
                    if (result.getCode() == 1 && result.getData() != null) {
                        ObservableList<CourseData> s=FXCollections.observableList(result.getData());
                        comb.setItems(s);
                        if (s.size() != 0) {
                            if(course_id!=null){
                                for(int i=0;i<s.size();i++){
                                    if(s.get(i).getId().equals(course_id)){
                                        comb.getSelectionModel().select(i);
                                        break;
                                    }
                                }
                            }else{
                                comb.getSelectionModel().select(selectedCourseIndex);
                            }
                        }
                    }else{
                        new DialogBuilder(courseDataLabel).setTitle("提示").setMessage("没有课程数据，请稍后再试").
                                setPositiveBtn("确定", "#ff3333").create();
                    }
                }).onException(e -> {
            e.printStackTrace();
            new DialogBuilder(courseDataLabel).setTitle("提示").setMessage("无法连接到服务器，请检查网络").
                    setPositiveBtn("确定", "#ff3333").create();
        }).withFinal(() -> {
            courseDataLabel.setText("题目所属课程: ");
        }).run();
    }

    @Override
    public void downloadFile(JFXButton downloadBtn) {
        ProcessChain.create().addRunnableInPlatformThread(() -> {
            downloadBtn.setText("下载中...");
            downloadBtn.setDisable(true);
        }).addSupplierInExecutor(() -> subjectApis.getTem())
                .addConsumerInPlatformThread((response) -> {
                    InputStream in = null;
                    FileOutputStream os = null;
                    try {
                        in = response.body().asInputStream();
                        DirectoryChooser directoryChooser = new DirectoryChooser();
                        File file1 = directoryChooser.showDialog(null);
                        String path = file1.getPath();//选择的文件夹路径
                        os = new FileOutputStream(path + "\\" + "批量导入题目模板.docx");
                        byte[] buffer = new byte[4 * 1024];
                        int read;
                        while ((read = in.read(buffer)) > 0) {
                            os.write(buffer, 0, read);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        new DialogBuilder(downloadBtn).setTitle("提示").setMessage("下载文件失败，请稍后再试").
                                setPositiveBtn("确定", "#ff3333").create();
                    } finally {
                        try {
                            if (os != null) {
                                os.close();
                            }
                            if (in != null) {
                                in.close();
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            new DialogBuilder(downloadBtn).setTitle("提示").setMessage("下载文件失败，请稍后再试").
                                    setPositiveBtn("确定", "#ff3333").create();
                        }
                    }
                }).withFinal(() -> {
            downloadBtn.setText("下载Word文档");
            downloadBtn.setDisable(false);
        }).run();
    }

    @Override
    public void uploadFile(File file, JFXButton uploadBtn, String selectCourseId, TableView<BulkImport> tableSize,
                           VBox form, VBox loadingUploadInfo, HBox btnGroupInfo, ObservableList<BulkImport> observableList, JFXCheckBox cb) {
        ProcessChain.create().addRunnableInPlatformThread(() -> {
            cb.setSelected(false);
            observableList.clear();
            uploadBtn.setText("上传文档中...");
            uploadBtn.setDisable(true);
            form.setManaged(false);
            form.setVisible(false);
            loadingUploadInfo.setVisible(true);
            loadingUploadInfo.setManaged(true);
        }).addSupplierInExecutor(() -> subjectApis.upload(FileUpload.fileToMultipartFile(file),selectCourseId)).addConsumerInPlatformThread((result -> {
            logger.info(result);
            if (result.getCode() == 1) {
                List<BulkImport> bulkList= result.getData();
                bulkList.forEach(bulkImport -> bulkImport.setChecked(false));
                observableList.addAll(bulkList);
                tableSize.setItems(observableList);
                tableSize.refresh();
                loadingUploadInfo.setVisible(false);
                loadingUploadInfo.setManaged(false);
                form.setManaged(true);
                form.setVisible(true);
            } else {
                new DialogBuilder(uploadBtn).setTitle("提示").setMessage(result.getMsg()).
                        setPositiveBtn("确定", "#ff3333").create();
            }
        })).onException(e -> {
            e.printStackTrace();
            new DialogBuilder(uploadBtn).setTitle("提示").setMessage("无法连接到服务器，请检查网络").
                    setPositiveBtn("确定", "#ff3333").create();
        }).withFinal(() -> {
            uploadBtn.setText("上传文档");
            uploadBtn.setDisable(false);
            loadingUploadInfo.setVisible(false);
            loadingUploadInfo.setManaged(false);
        }).run();
    }

    @Override
    public void addSub(JFXButton allImportBtn, SubjectDataListReq subjectDataListReq) {
        ProcessChain.create().addRunnableInPlatformThread(()->{
            allImportBtn.setText("导入中...");
            allImportBtn.setDisable(true);
        }).addSupplierInExecutor(()-> subjectApis.addSub(subjectDataListReq)).addConsumerInPlatformThread((result)->{
            if(result.getCode()==1){
                new DialogBuilder(allImportBtn).setTitle("提示").setMessage("导入成功").
                        setPositiveBtn("确定", "#3333cc").create();
            }else{
                new DialogBuilder(allImportBtn).setTitle("提示").setMessage("导入失败，请稍后再试").
                        setPositiveBtn("确定", "#ff3333").create();
            }
        }).onException(e->{
            e.printStackTrace();
            new DialogBuilder(allImportBtn).setTitle("提示").setMessage("无法连接到服务器，请检查网络").
                    setPositiveBtn("确定", "#ff3333").create();
        }).withFinal(()->{
            allImportBtn.setText("全部导入");
            allImportBtn.setDisable(false);
        }).run();
    }

    @Override
    public void getCourseSub(int currentPage, Integer rows, String keyword, JFXButton loading, String selectedCourseId, VBox loadingSubjectInfo, VBox subjectsContainer) {
        ProcessChain.create().addRunnableInPlatformThread(()->{
            subjectsContainer.getChildren().clear();
            loadingSubjectInfo.setVisible(true);loadingSubjectInfo.setManaged(true);
            subjectsContainer.setVisible(false);subjectsContainer.setManaged(false);
        }).addSupplierInExecutor(()-> subjectApis.getCourseSub(selectedCourseId,dataStore.getTeacher_id(),currentPage,rows,keyword)).addConsumerInPlatformThread((result)->{
            if(result.getCode()==1&&result.getData().size()!=0){
                List<SubjectTest> list=result.getData();
                int num=1;
                for (SubjectTest subjectTest : list) {
                    VBox vBox=newSubjectListController.genSubjectVBox(subjectTest,num);
                    subjectsContainer.getChildren().add(vBox);
                    num++;
                }
                subjectsContainer.setManaged(true);subjectsContainer.setVisible(true);
                loadingSubjectInfo.setManaged(false);loadingSubjectInfo.setVisible(false);
                newSubjectListController.setSubjectsTable(list.get(0).getTotal());
            }else{
                newSubjectListController.resetSubjectsTable();
                new DialogBuilder(loading).setTitle("提示").setMessage("没有题目数据，请稍后再试").
                        setPositiveBtn("确定", "#ff3333").create();
                subjectStore.setFirst(true);
            }
        }).onException(e->{
            e.printStackTrace();
            new DialogBuilder(loading).setTitle("提示").setMessage("无法连接到服务器，请检查网络").
                    setPositiveBtn("确定", "#ff3333").create();
            newSubjectListController.resetSubjectsTable();
            subjectStore.setFirst(true);
        }).run();
    }

    @Override
    public void getCourseChapterList(Label chapterLabel, ComboBox<CourseChapter> chapterComb, String id,
                                     String chapter_id) {
        ProcessChain.create().addRunnableInPlatformThread(()->{
            chapterLabel.setText("获取章节中...");
        }).addSupplierInExecutor(()-> subjectApis.getCourseChapterList(id,dataStore.getTeacher_id())).addConsumerInPlatformThread((result)->{
            if(result.getCode()==1&&result.getData()!=null){
                ObservableList<CourseChapter> courseChapters = FXCollections.observableArrayList(result.getData());
                chapterComb.setItems(courseChapters);
                for(int i=0;i<courseChapters.size();i++){
                    if(courseChapters.get(i).getId().equals(chapter_id)){
                        chapterComb.getSelectionModel().select(i);
                        break;
                    }
                }
            }else{
                new DialogBuilder(chapterLabel).setTitle("提示").setMessage("没有章节数据，请稍后再试").
                        setPositiveBtn("确定", "#ff3333").create();
            }
        }).onException(e -> {
            e.printStackTrace();
            new DialogBuilder(chapterLabel).setTitle("提示").setMessage("无法连接到服务器，请检查网络").
                    setPositiveBtn("确定", "#ff3333").create();
        }).withFinal(() -> {
            chapterLabel.setText("所属章节：");
        }).run();
    }

    @Override
    public void getCourseTargetRecord(Label targetLabel, String id, ComboBox<CourseTargetRecord> targetComb, String courseTargetId) {
        ProcessChain.create().addRunnableInPlatformThread(()->{
            targetLabel.setText("获取课程目标中...");
        }).addSupplierInExecutor(()-> subjectApis.getCourseTargetRecord(id,dataStore.getTeacher_id())).addConsumerInPlatformThread((result)->{
            if(result.getCode()==1&&result.getData()!=null){
                ObservableList<CourseTargetRecord> courseChapters = FXCollections.observableArrayList(result.getData());
                targetComb.setItems(courseChapters);
                for(int i=0;i<courseChapters.size();i++){
                    if(courseChapters.get(i).getId().equals(courseTargetId)){
                        targetComb.getSelectionModel().select(i);
                        break;
                    }
                }
            }else{
                new DialogBuilder(targetLabel).setTitle("提示").setMessage("没有课程目标数据，请稍后再试").
                        setPositiveBtn("确定", "#ff3333").create();
            }
        }).onException(e -> {
            e.printStackTrace();
            new DialogBuilder(targetLabel).setTitle("提示").setMessage("无法连接到服务器，请检查网络").
                    setPositiveBtn("确定", "#ff3333").create();
        }).withFinal(() -> {
            targetLabel.setText("课程目标：");
        }).run();
    }

    @Override
    public void getQuesTypeList(Label queTypeLabel, ComboBox<QuestionTypeRecord> questionTypeComb, String type_id) {
        ProcessChain.create().addRunnableInPlatformThread(()->{
            queTypeLabel.setText("获取题目类型中...");
        }).addSupplierInExecutor(()-> subjectApis.getQuesTypeList(dataStore.getTeacher_id())).addConsumerInPlatformThread((result)->{
            if(result.getCode()==1&&result.getData()!=null){
                ObservableList<QuestionTypeRecord> courseChapters = FXCollections.observableArrayList(result.getData());
                questionTypeComb.setItems(courseChapters);
                for(int i=0;i<courseChapters.size();i++){
                    if(courseChapters.get(i).getId().toString().equals(type_id)){
                        questionTypeComb.getSelectionModel().select(i);
                        break;
                    }
                }
            }else{
                new DialogBuilder(queTypeLabel).setTitle("提示").setMessage("没有题目类型数据，请稍后再试").
                        setPositiveBtn("确定", "#ff3333").create();
            }
        }).onException(e -> {
            e.printStackTrace();
            new DialogBuilder(queTypeLabel).setTitle("提示").setMessage("无法连接到服务器，请检查网络").
                    setPositiveBtn("确定", "#ff3333").create();
        }).withFinal(() -> {
            queTypeLabel.setText("题目类型：");
        }).run();
    }

    @Override
    public void modifySubject(SubjectDataInfo subjectDataInfo, TextField knowledgePoint) {
        ProcessChain.create().addSupplierInExecutor(()->{
            return subjectApis.updateSubInfo(new SubjectDataReq(subjectDataInfo,dataStore.getToken(),
                    dataStore.getTeacher_id()));
        }).addConsumerInPlatformThread((result)->{
            if(result.getCode()==1){
                new DialogBuilder(knowledgePoint).setTitle("提示").setMessage("更新成功").
                        setPositiveBtn("确定", "#3333cc").create();
            }else{
                new DialogBuilder(knowledgePoint).setTitle("提示").setMessage("更新失败，请稍后再试").
                        setPositiveBtn("确定", "#ff3333").create();
            }
        }).onException(e->{
            new DialogBuilder(knowledgePoint).setTitle("提示").setMessage("无法连接到服务器，请检查网络").
                    setPositiveBtn("确定", "#ff3333").create();
        }).run();
    }

    @Override
    public void updateSubInfo(SubjectDataReq subjectDataReq, JFXButton loading) {
        ProcessChain.create().addSupplierInExecutor(()-> subjectApis.updateSubInfo(subjectDataReq)).addConsumerInPlatformThread(result -> {
            if(result.getCode()==1){
                new DialogBuilder(loading).setTitle("提示").setMessage("修改成功").
                        setPositiveBtn("确定","#3333cc").create();
                newSubjectListController.InitSubjects(newSubjectListController.currentPage,
                        newSubjectListController.rows,null);
            }else{
                new DialogBuilder(loading).setTitle("提示").setMessage("修改失败").
                        setPositiveBtn("确定","#ff3333").create();
            }
        }).onException(e->{
            e.printStackTrace();
            new DialogBuilder(loading).setTitle("提示").setMessage("网络错误，请稍后再试").
                    setPositiveBtn("确定","#ff3333").create();
        }).run();
    }


}
